#include<stdio.h>
#include<gui.h>
#include<gui_window.h>
#include"edit_window.h"
#include"edit_cursor.h"
#include"edit_ctrl.h"

edit_cursor_t cursor;

char cursor_size[CS_MAX_NR][2] = {
    {8, 16},
    {8, 16}, 
    {1, 16},
    {8, 1},
};

void set_cursor_size()
{
    cursor.width=cursor_size[cursor.shape][0];
    cursor.height=cursor_size[cursor.shape][1];
}

void set_cursor_shape(uint8_t shape)
{
    cursor.shape=shape;
    set_cursor_size();
    draw_cursor();
}

void set_cursor_color(gui_color_t color)
{
    cursor.color=color;
    draw_cursor();
}

//clean cursor image and clean text,need again show text
void clean_cursor()
{
    int x=cursor.x*edit_ctrl.char_width;
    int y=cursor.y*edit_ctrl.char_height;

    edit_window_rectfill(x,y,edit_ctrl.char_width,edit_ctrl.char_height,edit_ctrl.back_color);
    edit_window_update(x, y, 
        x + edit_ctrl.char_width, y + edit_ctrl.char_height);
}


void cursor_pos_check()
{
    //cursor left move above 
    if(cursor.x<0)
    {   
        //back to last line end
        if(cursor.y>0)  
        {
            cursor.x=edit_ctrl.columns-1;
        }
        else 
        {
            cursor.x=0;
        }
        //move to last line
        cursor.y--;
    }

    //cursor right move above
    if(cursor.x>edit_ctrl.columns-1)
    {
        //move to next line start
        if(cursor.y<edit_ctrl.rows)
        {
            cursor.x=0;
        }
        else 
        {
            cursor.x=edit_ctrl.columns-1;
        }
        cursor.y++;
    }


    //up move above
    if(cursor.y<0)
    {
        cursor.y=0;
        cursor.visual=0;
    }
    else 
    {
        cursor.visual=1;
    }


    //down move above
    if(cursor.y>edit_ctrl.rows-1)
    {
        cursor.y=edit_ctrl.rows-1;
        scroll_screen(EDIT_CTRL_SCROLL_DOWN,1,1,0);
    }
    else 
    {
        cursor.visual=1;
    }
    
}

void move_cursor(int x,int y)
{
    //clean
    clean_cursor();

    //show character on source position
    char ch=0;
    edit_buffer_getchar(&ch,cursor.x,cursor.y); //get source character
    edit_ctrl_output_visual(ch,cursor.x*edit_ctrl.char_width,y*edit_ctrl.char_height);

    //move cursor
    cursor.x=x;
    cursor.y=y;
    cursor_pos_check();

    //show cursor
    draw_cursor();

    //show character on cursor position
    edit_buffer_getchar(&ch,cursor.x,cursor.y);
    edit_ctrl_output_visual(ch,cursor.x*edit_ctrl.char_width,y*edit_ctrl.char_height);
}

void move_cursor_off(int x,int y)
{
    move_cursor(cursor.x+x,cursor.y+y);
}

void draw_cursor()
{
    //no cursor visual
    if(!cursor.visual)
        return ;
    int x=cursor.x*edit_ctrl.char_width;
    int y=cursor.y*edit_ctrl.char_height;

    //draw background
    edit_window_rectfill(x,y,edit_ctrl.char_width,edit_ctrl.char_height,edit_ctrl.back_color);

    switch(cursor.shape)
    {
        case CS_SOLID_FRAME:
            edit_window_rectfill(x,y,cursor.width,cursor.height,cursor.color);
            break;
        case CS_HOLLOW_BOX:
            edit_window_rect(x,y,cursor.width,cursor.height,cursor.color);
            break;    
        case CS_VERTICAL_BAR:
            edit_window_rectfill(x,y,cursor.width,cursor.height,cursor.color);
            break;
        case CS_UNDERLINE:
            edit_window_rectfill(x,y+edit_ctrl.char_height-1,cursor.width,cursor.height,cursor.color);
            break;
        default:
            break;
    }
    edit_window_update(x,y,x+edit_ctrl.char_width,y+edit_ctrl.char_height);
}

//focus to cursor position
void focus_cursor()
{
    if(!cursor.visual)
        return ;
    if(cursor.y<0)
    {
        scroll_screen(EDIT_CTRL_SCROLL_UP,-cursor.y,0,1);
    }
    else if(cursor.y>=edit_ctrl.rows)
    {
        scroll_screen(EDIT_CTRL_SCROLL_DOWN,cursor.y-edit_ctrl.rows+1,0,1);
    }
}

int edit_cursor_init()
{
    cursor.x=0;
    cursor.y=0;
    cursor.shape=CS_SOLID_FRAME;

    set_cursor_size();

    cursor.color=EDIT_CURSOR_COLOR;
    cursor.visual=1; //default cursor status visual

    draw_cursor();
}